home *** CD-ROM | disk | FTP | other *** search
- /* CUTAPE */
- /*
- Write labelled tapes in either of two formats:
- . ANSI label ASCII format "D" (ANSI X3.27-1978, Level 3)
- . IBM OS standard label EBCDIC format "VB"
- */
- /*
- Authors: Jeff Damens, Grace Lee, Frank da Cruz
- Columbia University Center for Computing Activities
- 612 W 115 Street
- New York NY 10025
-
- Copyright (C) 1984, Trustees of Columbia University in the City of New York
- May be copied, reproduced, or adapted without permission except for
- explicitly commercial purposes.
- */
- /*
- * write an ebcdic standard labeled tape
- * jd, 9/84
- *
- * Added ansi tape capability, numerous improvements
- * grace, 10/84
- *
- * Added some performance optimizations
- * jd, 1/85
- *
- * Made ANSI tape show ANSI version 3 in VOL1, column 80
- * fdc, 2/86
- *
- * Added -f option to select tape drive, help message, ...
- * fdc, 5/87
- *
- * Merged a-to-e translation table into this source, so there's only
- * one source file.
- * fdc, 5/88
- *
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/ioctl.h>
- #include <sys/mtio.h>
- #include <sys/stat.h>
- #include <sys/dir.h>
-
- #define TRUE 1
- #define FALSE 0
- #define CRDATE 6 /* size of creation date field */
-
- /* flag for ebcdic and ascii tape */
-
- #define EBC 0
- #define ASC 1
-
- /*
- * Default blocksize and record length, and default tape drive to use.
- */
-
- #define BLKSIZE 8192
- #define LRECL 300
- #ifndef DEFTAPE
- #define DEFTAPE "/dev/rmt12"
- #endif
-
- /* global variables */
-
- int fd,filno=1;
- int blksize = BLKSIZE, lrecl = LRECL;
- int tmp,flag = EBC;
- int v1done = FALSE; /* no vol1 lbl written yet */
-
- char tape = 'e';
- char *volid = "KERMIT", *owner = ""; /* default label and owner */
- char *tapeid = DEFTAPE; /* default tape drive */
-
- struct plain {
- char c[80]; }; /* dummy template */
-
- /*
- * template for vol1 label
- *
- */
-
- struct vol1 { /* volume label for ebcdic tape */
- char labid[4], /* always VOL1 */
- volser[6], /* volume label */
- junk1[31], /* reserved */
- owner[10], /* volume owner */
- junk2[29]; };
-
- struct avol1 { /* volume label for ansi tape */
- char labid[4], /* always VOL1 */
- volser[6], /* volume label */
- junk1[27], /* reserved */
- owner[14], /* volume owner */
- junk2[28], /* (fdc) reserved */
- ansver[1]; }; /* (fdc) ANSI version */
-
- /*
- * template for HDR1/EOF1 label
- *
- */
-
- struct lab1 {
- char labid[4], /* hdr1 or eof1 */
- dsn[17], /* dataset name */
- volser[6], /* vol ser */
- volseq[4], /* volume sequence (0001) */
- dataseq[4], /* dataset sequence number */
- gen[4], /* generation # (blank) */
- genver[2], /* version of generation (blank) */
- credate[6], /* creation date */
- expdate[6], /* expiration date */
- secure, /* security (0) */
- blkcnt[6], /* block count */
- system[13], /* system code */
- junk[7]; }; /* reserved */
- /*
- * template for HDR2/EOF2 label
- *
- */
-
- struct lab2 { /* header label for ebcdic tape */
- char labid[4], /* hdr2 or eof2 */
- recfm, /* record format */
- blksize[5], /* block length */
- lrecl[5], /* record length */
- density, /* tape density */
- dsp, /* dataset position (0) */
- jsi[17], /* job step identification (ha) */
- trt[2], /* tape recording technique (blank) */
- cc, /* control char (blank) */
- res, /* reserved */
- blkattr, /* blocking type */
- res2[41]; }; /* more reserved */
-
- struct alab2 { /* header label for ascii tape */
- char labid[4], /* hdr2 or eof2 */
- recfm, /* record format */
- blksize[5], /* block length */
- lrecl[5], /* record length */
- junk1[35], /* reserved for system use */
- bufoff[2], /* buffer-offset length */
- junk2[28]; }; /* reserved */
-
- union label {
- struct vol1 v1;
- struct avol1 av1;
- struct lab1 l1;
- struct lab2 l2;
- struct alab2 al2;
- struct plain p };
-
- typedef union label *Label;
-
- /*
- ASCII/EBCDIC translation table, follows the IBM System/370 Reference
- Summary, GX20-1850-6, File No. S370/4300-01
- */
- char atoe[] = {
- 0, /* 0 */
- 1, /* 1 */
- 2, /* 2 */
- 3, /* 3 */
- 55, /* 4 */
- 45, /* 5 */
- 46, /* 6 */
- 47, /* 7 */
- 22, /* 8 */
- 5, /* 9 */
- 37, /* 10 */
- 11, /* 11 */
- 12, /* 12 */
- 13, /* 13 */
- 14, /* 14 */
- 15, /* 15 */
- 16, /* 16 */
- 17, /* 17 */
- 18, /* 18 */
- 108, /* 19 */
- 60, /* 20 */
- 61, /* 21 */
- 108, /* 22 */
- 108, /* 23 */
- 24, /* 24 */
- 25, /* 25 */
- 63, /* 26 */
- 39, /* 27 */
- 34, /* 28 */
- 108, /* 29 */
- 108, /* 30 */
- 108, /* 31 */
- 64, /* 32 */
- 90, /* 33 */
- 127, /* 34 */
- 123, /* 35 */
- 91, /* 36 */
- 108, /* 37 */
- 80, /* 38 */
- 125, /* 39 */
- 77, /* 40 */
- 93, /* 41 */
- 92, /* 42 */
- 78, /* 43 */
- 107, /* 44 */
- 96, /* 45 */
- 75, /* 46 */
- 97, /* 47 */
- 240, /* 48 */
- 241, /* 49 */
- 242, /* 50 */
- 243, /* 51 */
- 244, /* 52 */
- 245, /* 53 */
- 246, /* 54 */
- 247, /* 55 */
- 248, /* 56 */
- 249, /* 57 */
- 122, /* 58 */
- 94, /* 59 */
- 76, /* 60 */
- 126, /* 61 */
- 110, /* 62 */
- 111, /* 63 */
- 124, /* 64 */
- 193, /* 65 */
- 194, /* 66 */
- 195, /* 67 */
- 196, /* 68 */
- 197, /* 69 */
- 198, /* 70 */
- 199, /* 71 */
- 200, /* 72 */
- 201, /* 73 */
- 209, /* 74 */
- 210, /* 75 */
- 211, /* 76 */
- 212, /* 77 */
- 213, /* 78 */
- 214, /* 79 */
- 215, /* 80 */
- 216, /* 81 */
- 217, /* 82 */
- 226, /* 83 */
- 227, /* 84 */
- 228, /* 85 */
- 229, /* 86 */
- 230, /* 87 */
- 231, /* 88 */
- 232, /* 89 */
- 233, /* 90 */
- 173, /* 91 */
- 0xe0, /* 92 */
- 189, /* 93 */
- 95, /* 94 */
- 109, /* 95 */
- 0x79, /* 96 */
- 129, /* 97 */
- 130, /* 98 */
- 131, /* 99 */
- 132, /* 100 */
- 133, /* 101 */
- 134, /* 102 */
- 135, /* 103 */
- 136, /* 104 */
- 137, /* 105 */
- 145, /* 106 */
- 146, /* 107 */
- 147, /* 108 */
- 148, /* 109 */
- 149, /* 110 */
- 150, /* 111 */
- 151, /* 112 */
- 152, /* 113 */
- 153, /* 114 */
- 162, /* 115 */
- 163, /* 116 */
- 164, /* 117 */
- 165, /* 118 */
- 166, /* 119 */
- 167, /* 120 */
- 168, /* 121 */
- 169, /* 122 */
- 192, /* 123 */
- 79, /* 124 */
- 208, /* 125 */
- 0xa1, /* 126 */
- 108 /* 127 */
- };
-
- char curdate[CRDATE+1]; /* current date for ascii tape */
-
- /*
- * strip the path components from a filename. Returns a pointer to the
- * bare file name, so it can be written to a label.
- *
- */
-
- char *
- basename(x)
- char *x;
- {
- char *p,*rindex();;
- if ((p = rindex(x,'/')) == NULL) return(x);
- return(p+1);
- }
-
- /*
- * convert a filename so that it can be written to a tape label.
- * any path is stripped, and the name is uppercased. Returns a pointer
- * to the new name. The name is changed in place.
- *
- */
-
- char *
- cvtfnam(x)
- char *x;
- {
- char *fnptr;
- for (x = basename(x), fnptr = x; *x != '\0'; x++)
- if (islower(*x)) *x = toupper(*x);
- return(fnptr);
- }
-
- /*
- * clear a label by writing spaces in all the columns.
- *
- */
-
- clrlabel(l)
- Label l;
- {
- int i;
- for (i=0; i<80; i++) l->p.c[i] = ' ';
- }
-
- /*
- * write a numeric field to a label. Pass the destination address,
- * the number to be written and the # of columns the number is to occupy.
- * if zfill is TRUE, we pad with zeros (otherwise blanks).
- *
- */
- putnfld(dest,num,places,zfill)
- register char *dest;
- register int num;
- int places,zfill;
- {
- register char *d,f;
- d = dest + places - 1; /* end of buffer */
- do {
- *d-- = (num % 10) + '0';
- num /= 10; } while (num != 0);
- f = zfill ? '0' : ' ';
- while (d >= dest) *d-- = f;
- }
-
- /*
- * write a string field to a label. Pass the destination and source
- * addresses, the # of places to be filled.
- *
- */
-
- putsfld(dest,src,places)
- register char *dest,*src;
- register int places;
- {
- register char c;
- while (c = *src) {
- *dest++ = c;
- src++;
- places--; }
- while (places--) *dest++ = ' ';
- }
-
- /*
- * write a label to the given file descriptor. Pass the file descriptor
- * and a pointer to the (80 column) label. If the tape is ebcdic,
- * the label is converted to ebcdic before it is written to the tape.
- * Otherwise, it is written as ascii.
- *
- */
-
- wrlab(fd,blk,typ)
- int fd,typ;
- char *blk;
- {
- char eblk[80];
-
- if (typ == EBC)
- { cvtebc(eblk,blk);
- if (write(fd,eblk,80) != 80)
- wrerr("Error writing label - possibly off end of tape");
- }
- else if (write(fd,blk,80) != 80)
- wrerr("Error writing label - possibly off end of tape");
- }
-
- /*
- * check if the character is alphanumeric
- * if not, replace it by 'X'
- *
- */
-
- checkfn(fn)
- char *fn;
- {
- int period = 0;
- register int c;
- for (; c = *fn; fn++)
- if ((c == '.' && ++period > 1) ||
- (c != '.' && !isalnum(c))) *fn = 'X';
- }
-
-
- /*
- * write a tape mark to the tape
- *
- */
-
- wtm(fd)
- int fd;
- {
- struct mtop m;
- m.mt_op = MTWEOF;
- m.mt_count = 1;
- if (ioctl(fd,MTIOCTOP,(char *) &m) == -1) perror("mtioctl");
- }
-
- /*
- * rewind and unload the tape
- *
- */
- unl(fd)
- int fd;
- {
- struct mtop m;
- m.mt_op = MTOFFL;
- if (ioctl(fd,MTIOCTOP,(char *) &m) == -1) perror("unload failed");
- }
-
- /*
- * rewind the tape
- *
- */
-
- rew(fd)
- int fd;
- {
- struct mtop m;
- m.mt_op = MTREW;
- if (ioctl(fd,MTIOCTOP,(char *) &m) == -1) perror("rewind failed");
- }
-
- /*
- * copy the source string to the destination, converting to ebcdic.
- * this stops on a null byte.
- *
- */
-
- cvtebc(dst,src)
- char *dst,*src;
- {
- while (*dst++ = atoe[*src++]);
- }
-
- /*
- * write an ebcdic vol1 label, passed a tape file descriptor and the
- * volume label and owner strings
- *
- */
-
- wvol1(fd,volser,owner,flag)
- int fd,flag;
- char *volser,*owner;
- {
- union label l;
- clrlabel(&l); /* init all fields to spaces */
- strncpy(l.v1.labid,"VOL1",4);
- putsfld(l.v1.volser,cvtfnam(volser),6); /* put in volser */
- l.v1.junk1[0] = '0'; /* must be 0 (?) */
- putsfld(l.v1.owner,cvtfnam(owner),10); /* copy in owner name */
- wrlab(fd,(char *) &l,flag);
- }
-
- /*
- * write a vol1 label on ascii tape, passed a tape file descriptor and the
- * volume label and owner strings
- *
- */
-
- wavol1(fd,volser,owner,flag)
- int fd,flag;
- char *volser,*owner;
- {
- union label l;
- char *a;
- clrlabel(&l); /* init all fields to spaces */
- strncpy(l.av1.labid,"VOL1",4);
- putsfld(l.av1.volser,cvtfnam(volser),6); /* put in volser */
- l.av1.junk1[0] = ' ';
- putsfld(l.av1.owner,cvtfnam(owner),14); /* copy in owner name */
- strncpy(l.av1.ansver,"3",1); /* ANSI version */
- wrlab(fd,(char *) &l,flag);
- }
-
-
- /*
- * write a HDR1 or EOF1 label to the given file descriptor.
- * labtyp should be either HDR1 or EOF1,
- * dsn the filename to be written to the label,
- * volser the internal tape label,
- * dsseq the position of this file on the tape,
- * blkcnt 0 for a HDR1 label or the number of tape blocks in the file for EOF1.
- *
- */
-
- wlab1(fd,labtyp,dsn,volser,dsseq,blkcnt,flag)
- int fd,dsseq,blkcnt,flag;
- char *labtyp,*dsn,*volser;
- {
- char * getansidate();
- union label l;
- clrlabel(&l);
- strncpy(l.l1.labid,labtyp,4);
- checkfn(dsn);
- putsfld(l.l1.dsn,dsn,17);
- putsfld(l.l1.volser,cvtfnam(volser),6);
- putnfld(l.l1.volseq,1,4,TRUE); /* volseq is always 1 */
- putnfld(l.l1.dataseq,dsseq,4,TRUE); /* dataset sequence # */
- if (flag == ASC) {
- putsfld(l.l1.gen,"0001",4); /* generation is always 1 */
- putsfld(l.l1.genver,"00",2); /* generation version is 0 */
- }
- putsfld(l.l1.credate,curdate,6);
- putsfld(l.l1.expdate,curdate,6);
- if (flag == EBC)
- l.l1.secure = '0'; /* no security */
- else
- l.l1.secure = ' ';
- putnfld(l.l1.blkcnt,blkcnt,6,TRUE);
- wrlab(fd,(char *) &l,flag);
- }
-
- /*
- * write a HDR2/EOF2 label to the given tape file descriptor.
- * labtyp should be either HDR1 or EOF2.
- * blksiz and lrecl should be the tape blocksize and maximum record
- * length of the file.
- * record format currently forced to VB, density to 1600 BPI.
- *
- */
-
- wlab2(fd,labtyp,blksiz,lrecl,flag) /* ebcdic tape */
- int fd,blksiz,lrecl,flag;
- char *labtyp;
- {
- union label l;
- clrlabel(&l);
- strncpy(l.l2.labid,labtyp,4);
- l.l2.recfm = 'V'; /* variable length records */
- putnfld(l.l2.blksize,blksiz,5,TRUE);
- putnfld(l.l2.lrecl,lrecl,5,TRUE);
- l.l2.density = '3'; /* 1600 BPI */
- l.l2.dsp = '0';
- l.l2.blkattr = 'B'; /* blocked records */
- wrlab(fd,(char *) &l,flag);
- }
-
-
- /*
- * write an ansi HDR2/EOF2 label.
- * The only currently supported record format is 'D'.
- *
- */
-
- walab2(fd,labtyp,blksiz,lrecl,flag) /* ascii tape */
- int fd,blksiz,lrecl,flag;
- char *labtyp;
- {
- union label l;
- clrlabel(&l);
- strncpy(l.al2.labid,labtyp,4);
- l.al2.recfm = 'D'; /* variable length records */
- putnfld(l.al2.blksize,blksiz,5,TRUE);
- putnfld(l.al2.lrecl,lrecl,5,TRUE);
- putsfld(l.al2.bufoff,"00",2);
- wrlab(fd,(char *) &l,flag);
- }
-
- /*
- * write a file to the given tape file descriptor.
- * this writes the header and trailer labels and the contents of
- * the file, handling all necessary blocking. The file is written
- * to the tape in V format.
- * Also writes the file number and file name to standard output,
- * for listing purposes.
- *
- * fname should be the actual (UNIX) filename.
- * blksiz and lrecl should be the desired tape blocksize and max. record length
- * volser is the internal tape label
- * filno is the position of this file on the tape.
- *
- */
-
- wrfil(fd,fname,blksiz,lrecl,volser,filno,flag,length)
- int fd,blksiz,lrecl,filno,flag,length;
- char *fname,*volser;
- {
- static char *blkbuf = NULL,*recbuf = NULL;
- static int oblksiz, olrecl;
- FILE *fp;
- char *malloc(),*blkptr;
- register char *recptr,*ufname;
- int reccnt,blklen,reclen,blkcnt,i;
- if ((fp = fopen(fname,"r")) == NULL) {
- fprintf(stderr,"Can't open %s\n",fname);
- return; }
- ufname = cvtfnam(fname); /* convert a filename */
- printf("%3d %s\n",filno,ufname);
- blkcnt = 0;
- if (blkbuf == NULL || oblksiz < blksiz) {
- if (blkbuf) free(blkbuf); /* free any old buffer */
- if ((blkbuf = malloc(blksiz)) == NULL) fatal("Can't alloc block buffer");
- oblksiz = blksiz; /* remember size of buffer */
- }
- if (recbuf == NULL || olrecl < lrecl) {
- if ((recbuf = malloc(lrecl)) == NULL) fatal("Can't alloc record buffer");
- olrecl = lrecl; /* remember buffer size */
- }
- wlab1(fd,"HDR1",ufname,volser,filno,blkcnt,flag);
- if (flag == EBC)
- wlab2(fd,"HDR2",blksiz,lrecl,flag);
- else
- walab2(fd,"HDR2",blksiz,lrecl,flag);
- wtm(fd);
- reccnt = 1;
- blkptr = blkbuf + length; /* place where data starts */
- blklen = length; /* length of block */
- while (!feof(fp)) {
- register int c,cnt;
- cnt = lrecl;
- recptr = recbuf;
- while (--cnt && (c = getc(fp)) != EOF && c != '\n') *recptr++ = c;
- *recptr = '\0'; /* tie off record */
- reclen = lrecl - cnt - 1;
- if (c != '\n' && c != EOF) {
- while ((c = getc(fp)) != EOF && c != '\n');
- fprintf(stderr,"In file %s, record %d truncated\n",ufname,reccnt);
- }
- if (reclen == 0) {
- if (c == EOF) break; /* at end of file, forget it */
- if (flag == EBC) {
- recbuf[0] = ' '; /* cant write empty records */
- reclen = 1;
- }
- }
- reccnt++;
- reclen += 4; /* count actual record length */
- if (blklen + reclen > blksiz) /* buffer going to be full? */
- { /* yes, empty buffer first */
- if (flag == EBC) {
- blkbuf[0] = blklen >> 8;
- blkbuf[1] = blklen & 0xff; /* fill in block length */
- blkbuf[2] = blkbuf[3] = 0; }
- else /* fill ansi block to mult of 4 */
- while (blklen % 4 != 0) *blkptr++ = '^', blklen++;
- if (write(fd,blkbuf,blklen) != blklen)
- wrerr("Error writing block - possibly off end of tape");
- blkcnt++;
- blkptr = blkbuf + length; /* init ptr again */
- blklen = length;
- }
- blklen += reclen; /* include this record */
- if (flag == EBC) { /* record length in binary */
- *blkptr++ = reclen >> 8; /* high order */
- *blkptr++ = reclen & 0xff; /* low order */
- *blkptr++ = 0;
- *blkptr++ = 0; } /* two filler bytes... */
- else {
- putnfld(blkptr,reclen,4,TRUE); /* record length in */
- blkptr += 4; }
- reclen -= 4; /* subtract overhead for loop */
- if (flag == EBC)
- for (recptr = recbuf; reclen > 0; reclen--)
- *blkptr++ = atoe[*recptr++];
- else /* dupl loop so dont test each chr */
- for (recptr = recbuf; reclen > 0; reclen--)
- *blkptr++ = *recptr++;
- } /* end of while */
-
- if (blklen > length) /* anything in last block? */
- {
- if (flag == EBC) {
- blkbuf[0] = blklen >> 8;
- blkbuf[1] = blklen & 0xff; /* fill in block length */
- blkbuf[2] = blkbuf[3] = 0;}
- else /* pad ansi tape to mult of 4 */
- while (blklen % 4 != 0) *blkptr++ = '^', blklen++;
-
- if (write(fd,blkbuf,blklen) != blklen)
- wrerr("Error writing block - possibly off end of tape");
- blkcnt++;
- }
- wtm(fd);
- wlab1(fd,"EOF1",ufname,volser,filno,blkcnt,flag);
- if (flag == EBC)
- wlab2(fd,"EOF2",blksiz,lrecl,flag);
- else
- walab2(fd,"EOF2",blksiz,lrecl,flag);
- wtm(fd);
- fclose(fp);
- }
-
- /*
- * main routine - handles command parsing, writes VOL1 label.
- *
- */
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- if (argc < 2) usage();
-
- getansidate(curdate); /* get date for labels */
-
- while (*++argv)
- if (**argv == '-') /* Parse options */
- switch((*argv)[1])
- {
- case 'v' : volid = *++argv; break;
- case 'o' : owner = *++argv; break;
- case 'b' : if ((tmp = atoi(*++argv)) < 10)
- printf("illegal blocksize\n");
- else blksize = tmp;
- break;
- case 'l' : if ((tmp = atoi(*++argv)) < 10)
- printf("illegal lrecl\n");
- else lrecl = tmp;
- break;
- case 't' : if (**++argv == 'e')
- { tape = 'e';
- flag = EBC; }
- else if (**argv == 'a')
- { tape = 'a';
- flag = ASC; }
- else printf("illegal tape selection\n");
- break;
- case 'f' : tapeid = *++argv; break;
-
- default : usage();
- }
- else {
- if (!v1done)
- {
- if ((fd = open(tapeid,1)) == -1) fatal("can't open tape");
- rew(fd);
- if (flag != EBC)
- blksize = (blksize + 3) & ~3; /* if ansi, blksize is mult of 4 */
- printf("Tape %s, volume %s, owner %s\n",tapeid,volid,owner);
- printf("recfm %s, blocksize %d, lrecl %d, type %c\n\n",
- flag == EBC ? "VB" : "D",blksize,lrecl,tape);
- if (flag == EBC)
- wvol1(fd,volid,owner,flag);
- else
- wavol1(fd,volid,owner,flag);
- v1done = TRUE;
- }
- filno = wrdir(fd,*argv,blksize,lrecl,volid,filno,flag);
- }
- wtm(fd);
- close(fd);
-
-
-
- if ((fd = open(tapeid,0)) == -1) fatal("can't reopen tape");
- rew(fd);
- close(fd);
- }
-
- /*
- * write a directory to the tape. If the path is just a regular file,
- * write it to the tape. Otherwise open the directory and recursively
- * write all the files in it to the tape. Returns an updated filno, eg
- * filno + # of files written.
- *
- */
-
- int
- wrdir(fd,path,blksize,lrecl,volid,filno,flag)
- int fd,blksize,lrecl,filno,flag;
- char *path,*volid;
- {
- struct stat sbuf;
- DIR *dp;
- struct direct *dirent;
- char tmpname[300];
- int length;
-
- if (stat(path,&sbuf) == -1) {
- fprintf(stderr,"%s not found\n",path);
- return(filno); }
- if ((sbuf.st_mode & S_IFREG) != 0) { /* regular file, just put on tape */
- if (flag == EBC) { /* ebcdic tape */
- length = 4;
- wrfil(fd,path,blksize,lrecl,volid,filno,flag,length);
- return(filno+1); }
- else { /* ascii tape */
- length = 0;
- wrfil(fd,path,blksize,lrecl,volid,filno,flag,length);
- return(filno+1); }
- }
- if ((sbuf.st_mode & S_IFDIR) != 0) { /* directory file */
- if ((dp = opendir(path)) == NULL) {
- fprintf(stderr,"Can't read directory ");
- perror(path);
- return(filno); }
- while ((dirent = readdir(dp)) != NULL) {
- if (dirent->d_name[0] == '.') continue;
- sprintf(tmpname,"%s/%s",path,dirent->d_name);
- filno = wrdir(fd,tmpname,blksize,lrecl,volid,filno,flag); }
- closedir(dp);
- return(filno); }
- else {
- fprintf(stderr,"%%%s not regular file or directory, skipping\n",
- path);
- return(filno); }
- }
-
- /*
- * fatal error handler - prints the given message and the last
- * system error, then aborts so that we get a core dump.
- *
- */
-
- fatal(msg)
- char *msg;
- {
- perror(msg);
- abort();
- }
-
-
- /*
- * wrerr - print a tape write error and exit with a non-zero condition
- * code (but don't core dump).
- *
- */
- wrerr(msg)
- char *msg;
- {
- fprintf(stderr,"%s\n",msg);
- printf("?Error: %s\n",msg); /* print to error and listing */
- exit(10);
- }
-
-
- /* getansidate -- return the current date in ansi format
- *
- * Ansi dates are strings of the form " yyddd" where
- * yy = the year and ddd = the day in the year. There must
- * be an initial blank.
- */
-
- char *
- getansidate(curdate)
- char *curdate;
- {
- time_t now, time();
- struct tm *timep, *localtime();
-
- now = time(NULL);
- timep = localtime(&now);
- sprintf(curdate," %02d%03d",timep->tm_year,timep->tm_yday);
- return(curdate);
-
- }
-
- usage() {
- printf("usage: cutape options files\n");
- printf("options: vobltf\n");
- printf("v - volume id, default %s\n",volid);
- printf("o - tape owner id, default (none)\n");
- printf("b - blocksize, default %d\n",blksize);
- printf("l - maximum logical record length, default %d\n",lrecl);
- printf("t - type: a for ANSI format D, e for ebcdic OS SL, ");
- printf("default %c\n",tape);
- printf("f - tape drive to use, default %s\n",tapeid);
- exit(1);
- }
-
-